SwiftGen から ImageResource & ColorResource に正規表現で置換する
前提
- 画面ごとに Swift Package によって module 分割している
- 共有リソースは
CommonAssetというネームスペースにしている。- JSON で表すと
{ "params": { "enumName": "CommonAsset", "publicAccess": true } }という感じ。 - こちらもやろうと思えば
ImageResource/ColorResourceに移行できるが、 public 定義が面倒なので一旦スキップ
- JSON で表すと
- strings ファイルだけは引き続き SwiftGen を利用する
- String Catalog (xcstrings) は多言語対応する際は非常に有用
- しかし、今回対応したアプリは単一言語のみサポートしており、strings を利用している理由もタイプセーフに strings ファイルを参照したいというモチベーションであるため。
regex
- Color:
(?<!Common)Asset(\.Colors)?\.([a-zA-Z_][a-zA-Z0-9_]*)\.color→UIColor(resource: .$2)(?<!Common)Asset(\.Colors)?\.([a-zA-Z_][a-zA-Z0-9_]*)\.swiftUIColor→Color(.$2)
- Image:
(?<!Common)Asset(\.Images)?\.([a-zA-Z_][a-zA-Z0-9_]*)\.image→UIImage(resource: .$2)(?<!Common)Asset(\.Image)?\.([a-zA-Z_][a-zA-Z0-9_]*)\.swiftUIImage→Image(.$2)Image\(asset: (?<!Common)Asset(\.Images)?\.([a-zA-Z_][a-zA-Z0-9_]*)\)→Image(.$2)
補足
CommonAssetは引き続き利用する共有リソースなので、除外している- 否定後読みを利用して除外している。
- 参考: 正規表現の先読み・後読み
AssetのあとにImagesやColorsネームスペースが続く場合と続かない場合があるので(\.Colors)?や(\.Images)?で 0 or 1 回にマッチさせている- 三項演算子で同一行に複数
Assetが登場する場合があるので、変数名は少し厳し目にマッチさせている\.([a-zA-Z_][a-zA-Z0-9_]*)の部分。ピリオドが来なければ多分大丈夫。- 例えば
color = isSelected ? Asset.Colors.selected.color : Asset.Colors.normal.colorみたいな場合にそれぞれにマッチさせたかった。